home *** CD-ROM | disk | FTP | other *** search
- /* $Id: rtp.c,v 1.9 2001/01/15 15:16:08 aleidinger Exp $ */
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
- #endif
-
- #include <stdio.h>
-
- #ifdef STDC_HEADERS
- # include <stdlib.h>
- # include <string.h>
- #else
- # ifndef HAVE_STRCHR
- # define strchr index
- # define strrchr rindex
- # endif
- char *strchr (), *strrchr ();
- # ifndef HAVE_MEMCPY
- # define memcpy(d, s, n) bcopy ((s), (d), (n))
- # define memmove(d, s, n) bcopy ((s), (d), (n))
- # endif
- #endif
-
- #ifdef HAVE_UNISTD_H
- # include <unistd.h>
- #endif
-
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
-
- #ifdef WITH_DMALLOC
- #include <dmalloc.h>
- #endif
-
- struct rtpbits {
- int sequence:16; /* sequence number: random */
- int pt:7; /* payload type: 14 for MPEG audio */
- int m:1; /* marker: 0 */
- int cc:4; /* number of CSRC identifiers: 0 */
- int x:1; /* number of extension headers: 0 */
- int p:1; /* is there padding appended: 0 */
- int v:2; /* version: 2 */
- };
-
- struct rtpheader { /* in network byte order */
- struct rtpbits b;
- int timestamp; /* start: random */
- int ssrc; /* random */
- int iAudioHeader; /* =0?! */
- };
-
- void
- initrtp (struct rtpheader *foo)
- {
- foo->b.v = 2;
- foo->b.p = 0;
- foo->b.x = 0;
- foo->b.cc = 0;
- foo->b.m = 0;
- foo->b.pt = 14; /* MPEG Audio */
- #ifdef FEFE
- foo->b.sequence = 42;
- foo->timestamp = 0;
- #else
- foo->b.sequence = rand () & 65535;
- foo->timestamp = rand ();
- #endif
- foo->ssrc = rand ();
- foo->iAudioHeader = 0;
- }
-
- int
- sendrtp (int fd, struct sockaddr_in *sSockAddr, struct rtpheader *foo,
- const void *data, int len)
- {
- char *buf = alloca (len + sizeof (struct rtpheader));
- int *cast = (int *) foo;
- int *outcast = (int *) buf;
- outcast[0] = htonl (cast[0]);
- outcast[1] = htonl (cast[1]);
- outcast[2] = htonl (cast[2]);
- outcast[3] = htonl (cast[3]);
- memmove (buf + sizeof (struct rtpheader), data, len);
- return sendto (fd, buf, len + sizeof (*foo), 0,
- (struct sockaddr *) sSockAddr, sizeof (*sSockAddr));
- /* return write(fd,buf,len+sizeof(*foo))==len+sizeof(*foo); */
- }
-
- /* create a sender socket. */
- int
- makesocket (char *szAddr, unsigned short port, unsigned char TTL,
- struct sockaddr_in *sSockAddr)
- {
- int iRet, iLoop = 1;
- struct sockaddr_in sin;
- unsigned char cTtl = TTL;
- char cLoop = 0;
- unsigned int tempaddr;
-
- int iSocket = socket (AF_INET, SOCK_DGRAM, 0);
- if (iSocket < 0) {
- fprintf (stderr, "socket() failed.\n");
- exit (1);
- }
-
- tempaddr = inet_addr (szAddr);
- sSockAddr->sin_family = sin.sin_family = AF_INET;
- sSockAddr->sin_port = sin.sin_port = htons (port);
- sSockAddr->sin_addr.s_addr = tempaddr;
-
- iRet = setsockopt (iSocket, SOL_SOCKET, SO_REUSEADDR, &iLoop, sizeof (int));
- if (iRet < 0) {
- fprintf (stderr, "setsockopt SO_REUSEADDR failed\n");
- exit (1);
- }
-
- if ((ntohl (tempaddr) >> 28) == 0xe) {
- /* only set multicast parameters for multicast destination IPs */
- iRet =
- setsockopt (iSocket, IPPROTO_IP, IP_MULTICAST_TTL, &cTtl,
- sizeof (char));
- if (iRet < 0) {
- fprintf (stderr,
- "setsockopt IP_MULTICAST_TTL failed. multicast in kernel?\n");
- exit (1);
- }
-
- cLoop = 1; /* !? */
- iRet = setsockopt (iSocket, IPPROTO_IP, IP_MULTICAST_LOOP,
- &cLoop, sizeof (char));
- if (iRet < 0) {
- fprintf (stderr,
- "setsockopt IP_MULTICAST_LOOP failed. multicast in kernel?\n");
- exit (1);
- }
- }
-
- return iSocket;
- }
-
-
-
-
- #if 0
- //
- // code contributed by Anonymous source. Supposed to be much better
- // then original code, but only seems to run on windows with MSVC.
- // and I cannot test it
- //
- #include <stdlib.h>
- #include <string.h>
- #include <netinet/in.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
-
- struct rtpbits {
- int sequence:16; /* sequence number: random */
- int pt:7; /* payload type: 14 for MPEG audio */
- int m:1; /* marker: 0 */
- int cc:4; /* number of CSRC identifiers: 0 */
- int x:1; /* number of extension headers: 0 */
- int p:1; /* is there padding appended: 0 */
- int v:2; /* version: 2 */
- };
-
- struct rtpheader { /* in network byte order */
- struct rtpbits b;
- int timestamp; /* start: random */
- int ssrc; /* random */
- int iAudioHeader; /* =0?! */
- };
-
- void
- rtp_initialization
- (
- struct rtpheader *foo
- )
- {
- foo->b.v=2;
- foo->b.p=0;
- foo->b.x=0;
- foo->b.cc=0;
- foo->b.m=0;
- foo->b.pt=14; /* MPEG Audio */
- #ifdef FEFE
- foo->b.sequence=42;
- foo->timestamp=0;
- #else
- foo->b.sequence=rand() & 65535;
- foo->timestamp=rand();
- #endif
- foo->ssrc=rand();
- foo->iAudioHeader=0;
- }
-
- int
- rtp_send
- (
- SOCKET s,
- struct rtpheader *foo,
- void *data,
- int len
- )
- {
- char *buffer=malloc(len+sizeof(struct rtpheader));
- int *cast=(int *)foo;
- int *outcast=(int *)buffer;
- int count, size ;
-
- outcast[0]=htonl(cast[0]);
- outcast[1]=htonl(cast[1]);
- outcast[2]=htonl(cast[2]);
- outcast[3]=htonl(cast[3]);
- memmove (buffer+sizeof(struct rtpheader),data,len);
- // return sendto (fd,buf,len+sizeof(*foo),0,(struct sockaddr *)sSockAddr,sizeof(*sSockAddr));
- /* return write(fd,buf,len+sizeof(*foo))==len+sizeof(*foo); */
- size = len + sizeof (*foo) ;
- count = send (s, buffer, size, 0) ;
- free (buffer) ;
-
- return count != size ;
- }
-
- /* create a sender socket. */
- int
- rtp_socket
- (
- SOCKET *ps,
- char *address,
- unsigned short port,
- int TTL
- )
- {
- // int iRet ;
- int iLoop = 1 ;
- // struct sockaddr_in sin ;
- char cTTL = (char)TTL ;
- char cLoop=0 ;
- // unsigned int tempaddr ;
- BOOL True = TRUE ;
- INT error ;
- char *c = "" ;
- UINT ip ;
- PHOSTENT host ;
- SOCKET s ;
- SOCKADDR_IN source, dest ;
- /*
- int s = socket (AF_INET, SOCK_DGRAM, 0) ;
- if (s < 0)
- {
- fprintf(stderr,"socket() failed.\n");
- exit(1);
- }
-
- tempaddr=inet_addr(address);
- sSockAddr->sin_family = sin.sin_family = AF_INET;
- sSockAddr->sin_port = sin.sin_port = htons(port);
- sSockAddr->sin_addr.s_addr = tempaddr;
-
- iRet = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *) &iLoop,
- sizeof(int));
- if (iRet < 0)
- {
- fprintf(stderr,"setsockopt SO_REUSEADDR failed\n");
- exit(1);
- }
-
- if ((ntohl(tempaddr) >> 28) == 0xe)
- {
- // only set multicast parameters for multicast destination IPs
- iRet = setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, &cTTL,
- sizeof(char));
- if (iRet < 0) {
- fprintf(stderr,"setsockopt IP_MULTICAST_TTL failed. multicast
- in kernel?\n");
- exit(1);
- }
-
- cLoop = 1; // !?
- iRet = setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP,
- &cLoop, sizeof(char));
- if (iRet < 0)
- {
- fprintf(stderr,"setsockopt IP_MULTICAST_LOOP failed.
- multicast in kernel?\n");
- exit(1);
- }
- }
- */
- source.sin_family = AF_INET ;
- source.sin_addr.s_addr = htonl (INADDR_ANY) ;
- source.sin_port = htons (0) ;
-
- dest.sin_family = AF_INET;
- dest.sin_addr.s_addr = inet_addr (address) ;
-
- if (!strcmp (address, "255.255.255.255"))
- {
- }
- else if (dest.sin_addr.s_addr == INADDR_NONE)
- {
- host = gethostbyname (address) ;
-
- if (host)
- {
- dest.sin_addr = *(PIN_ADDR) host->h_addr ;
- }
- else
- {
- printf ("Unknown host %s\r\n", address) ;
- return 1 ;
- }
- }
-
- dest.sin_port = htons ((u_short) port) ;
-
- ip = ntohl (dest.sin_addr.s_addr) ;
-
- if (IN_CLASSA(ip)) c = "class A" ;
- if (IN_CLASSB(ip)) c = "class B" ;
- if (IN_CLASSC(ip)) c = "class C" ;
- if (IN_CLASSD(ip)) c = "class D" ;
- if (ip == INADDR_LOOPBACK) c = "loopback" ;
- if (ip == INADDR_BROADCAST) c = "broadcast" ;
-
- s = socket (AF_INET, SOCK_DGRAM, PF_UNSPEC) ;
-
- if (s == INVALID_SOCKET)
- {
- error = WSAGetLastError () ;
- printf ("socket () error %d\r\n", error) ;
- return error ;
- }
-
- error = setsockopt (s, SOL_SOCKET, SO_REUSEADDR, (const char *) &True,
- sizeof (BOOL)) ;
-
- error = bind (s, (struct sockaddr *) &source, sizeof (source)) ;
-
- if (error == SOCKET_ERROR)
- {
- error = WSAGetLastError () ;
- printf ("bind () error %d\r\n", error) ;
- closesocket (s) ;
- return error ;
- }
-
- if (ip == INADDR_BROADCAST)
- {
- printf ("broadcast %s:%u %s\r\n", inet_ntoa (dest.sin_addr), ntohs
- (dest.sin_port), c) ;
-
- error = setsockopt (s, SOL_SOCKET, SO_BROADCAST, (const char *)
- &True, sizeof (BOOL)) ;
-
- if (error == SOCKET_ERROR)
- {
- error = WSAGetLastError () ;
- printf ("setsockopt (%u, SOL_SOCKET, SO_BROADCAST, ...) error %d\r\n", s, error) ;
- closesocket (s) ;
- return error ;
- }
- }
-
- if (IN_CLASSD(ip))
- {
- printf ("multicast %s:%u %s\r\n", inet_ntoa (dest.sin_addr), ntohs (dest.sin_port), c) ;
-
- // error = setsockopt (s, IPPROTO_IP, IP_MULTICAST_TTL, (const char *) &TTL, sizeof (int)) ;
- error = setsockopt (s, IPPROTO_IP, 3, (const char *) &TTL, sizeof (int)) ;
-
- if (error == SOCKET_ERROR)
- {
- error = WSAGetLastError () ;
- printf ("setsockopt (%u, IPPROTO_IP, IP_MULTICAST_TTL, ...) error %d\r\n", s, error) ;
- closesocket (s) ;
- return error ;
- }
- }
-
- error = connect (s, (PSOCKADDR) &dest, sizeof (SOCKADDR_IN)) ;
-
- if (error == SOCKET_ERROR)
- {
- printf ("connect: error %d\n", WSAGetLastError ()) ;
- closesocket (s) ;
- return error ;
- }
-
- *ps = s ;
-
- return 0 ;
- }
-
-
-
- #endif
-